package com.lizonghui.googleplay.manager;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Created by Administrator on 2016/6/18.
 * 线程池代理，对线程操作的一些封装，只需要暴露用户真正需要的操作
 * 提交任务，执行任务，移除任务
 */
public class ThreadPoolProxy {
    ThreadPoolExecutor mExecutor;

    private int mCorePoolSize;
    private int mMaximumPoolSize;
    private long mKeepAliveTime;


    //留出3个参数，让使用者去定义
    public ThreadPoolProxy(int corePoolSize, int maximumPoolSize, long keepAliveTime) {
        mCorePoolSize = corePoolSize;
        mMaximumPoolSize = maximumPoolSize;
        mKeepAliveTime = keepAliveTime;
    }

    private void initThreadPoolExecutor() {

        if (mExecutor == null || mExecutor.isShutdown() || mExecutor.isTerminated()) {
            int corePoolSize = mCorePoolSize;
            int maximumPoolSize = mMaximumPoolSize;
            long keepAliveTime = mKeepAliveTime;

            TimeUnit unit = TimeUnit.MILLISECONDS;
            BlockingQueue<Runnable> workQueue = new LinkedBlockingDeque<>();
            ThreadFactory threadFactory = Executors.defaultThreadFactory();
            RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardPolicy();

            //双重判断单例模式
            synchronized (ThreadPoolProxy.class){
                if(mExecutor == null || mExecutor.isShutdown() || mExecutor.isTerminated()){
                    mExecutor = new ThreadPoolExecutor(
                            corePoolSize,//核心线程数
                            maximumPoolSize,//最大线程数
                            keepAliveTime,//保持时间
                            unit,//时间单位
                            workQueue,//任务队列
                            threadFactory,//线程工程
                            handler);//异常处理器
                }
            }
        }
    }
    /**
     * 提交任务和之心任务区别：
     * 1 是否有返回值
     *     提交任务有返回值
     *      执行任务没有
     * 2future是啥？
     *     1得到任务执行结果
     *     2包含一个get方法和一个cancel方法
     *     3get方法是一个阻塞方法，会阻塞等待任务执行结果,还可以try catch任务执行过程中抛出的异常
     */

    /**
     * 提交任务
     */
    public Future<?> submit(Runnable task) {
        initThreadPoolExecutor();
        Future<?> submit = mExecutor.submit(task);
        return submit;
    }

    /**
     * 执行任务
     */
    public void execute(Runnable task) {
        initThreadPoolExecutor();
        mExecutor.execute(task);
    }

    /**
     * 移除任务
     */
    public void remove(Runnable task) {
        initThreadPoolExecutor();
        mExecutor.remove(task);
    }
}
